﻿namespace Groundwork.MVVM
{
    using Groundwork.Core;
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Allows you to communicate between loosly coupled components.
    /// </summary>
    public class EventHub
    {
        /// <summary>
        /// Event Dictionary that will store all the events and delegates
        /// </summary>
        private static ObservableDictionary<string, List<Action<object>>> eventDictionary = new ObservableDictionary<string, List<Action<object>>>();

        /// <summary>
        /// Subscribes the an event within the application. When the event is raised the eventCallback is triggered
        /// </summary>
        /// <param name="eventName">event name to register</param>
        /// <param name="eventCallback">event callback to trigger when event is raised</param>
        public void Subscribe(string eventName, Action<object> eventCallback)
        {
            string eventNameKey = eventName.ToLower();
            if (!eventDictionary.ContainsKey(eventNameKey))
            {
                eventDictionary.Add(eventNameKey, new List<Action<object>> { eventCallback });
            }
            else
            {
                var eventCallbackList = eventDictionary[eventNameKey];
                eventCallbackList.Add(eventCallback);
            }
        }

        /// <summary>
        /// Publishes an event within the application. When the event is all subscribers are notified and there event callbacks triggered.
        /// </summary>
        /// <param name="eventName">event name to publish to</param>
        /// <param name="data">data to publish</param>
        public void Publish(string eventName, object data)
        {
            string eventNameKey = eventName.ToLower();
            if (eventDictionary.ContainsKey(eventNameKey))
            {
                var eventCallbackList = eventDictionary[eventNameKey];
                foreach (var action in eventCallbackList)
                {
                    action(data);
                }
            }
        }

        /// <summary>
        /// Removes an event from the event hub
        /// </summary>
        /// <param name="eventName">name of event to remove</param>
        public static void Unsubscribe(string eventName)
        {
            string eventNameKey = eventName.ToLower();
            if (eventDictionary.ContainsKey(eventNameKey))
            {
                eventDictionary.Remove(eventNameKey);
            }
        }

        /// <summary>
        /// Removes all events from the event hub
        /// </summary>
        public static void UnsubscribeAll()
        {
            eventDictionary.Clear();
        }
    }
}
